<script setup>
import { ref, reactive, provide } from "vue";
import draggable from "vuedraggable/src/vuedraggable";
import FormPropsEditor from "../innerControls/FormPropsEditor.vue";
import types from "../innerControls/index";
import { randomWord, stringifyJson, parseJson } from "../utils";
//组件的属性
let props = defineProps({
  /**
   * props --表单属性
   * controls---表单中组件实例集合
   */
  formData: {
    type: Object,
    required: true,
  },
  /**
   * 表单设计器中，内置表单组件
   */
  controlGroups: {
    type: Array,
    default: [
      {
        name: "基础组件",
        controls: ["input"],
        types: [],
      },
    ],
  },
  /**
   * 表单设计器中，自定义组件
   */
  customComponents: {
    type: Array,
    default: [
      {
        group: "自定义组件",
        components: {},
      },
    ],
  },
});

/**
 * 加载自定义组件，并处理 表单设计器中   组件的实例
 */
function handCustomComponents() {
  const customComps = props.customComponents;
  if (customComps.length > 0) {
    customComps.forEach((item) => {
      let group = props.controlGroups.find((g) => g.name === item.groupName);
      if (!group) {
        group = {
          name: item.group,
          controls: [],
          types: [],
        };
        props.controlGroups.push(group);
      }

      for (let key in item.components) {
        group.controls.push(key);
      }
    });
  }

  //组件的实例
  props.controlGroups.forEach((group) => {
    group.types = group.controls.map((key) => {
      return types[key].Control;
    });
  });
}
handCustomComponents();

// UI所需数据
let data = reactive({
  activeControl: null,
  propTab: "control",
  device: "pc",
});
provide("data", data);
provide("formProps", props.formData.props);

function initFormData() {
  let defaultFormProps = {
    labelPosition: "right",
    labelWidth: 100,
    size: "default",
    cols: 24,
  };

  if (props.formData.props == undefined) {
    props.formData.props = defaultFormProps;
  } else {
    props.formData.props = Object.assign(
      defaultFormProps,
      props.formData.props
    );
  }

  if (props.formData.controls == undefined) {
    props.formData.controls = [];
  }
}

initFormData();

//添加控件
function addControl(ctlType) {
  const control = new ctlType();
  props.formData.controls.push(control);
  data.activeControl = control;
}

//克隆控件
function clone(ctlType) {
  const control = new ctlType();
  return control;
}
//清空控件
function clearControl() {
  for (let i = props.formData.controls.length - 1; i >= 0; i--) {
    let control = props.formData.controls[i];
    if (!control.lock) {
      props.formData.controls.splice(i, 1);
      if (control == data.activeControl) {
        data.activeControl = null;
      }
    }
  }
}
</script>

<template>
  <div class="container">
    <!-- 设计器左侧的组件面板 start -->
    <div class="left-board">
      <div v-for="group in controlGroups">
        <div class="com-title">
          <el-icon>
            <!-- <NameIcon name="component" /> -->
          </el-icon>
          <span>{{ group.name }}</span>
        </div>

        <draggable
          :list="group.types"
          item-key="type"
          tag="ul"
          class="com-group"
          :clone="clone"
          :sort="false"
          :group="{ name: 'com', pull: 'clone', put: false }"
        >
          <template #item="{ element }">
            <li class="com-label" @click="addControl(element)">
              <!-- <el-icon>
                <NameIcon :name="element.type" :icon="element.icon" />
              </el-icon> -->
              <span>{{ element.label }}</span>
            </li>
          </template>
        </draggable>
      </div>
    </div>
    <!-- 设计器左侧的组件面板 end -->
    <!-- 设计器中间的表单设计区域 start -->

    <div class="center-board">
      <div class="toolbar">
        <!-- <div class="epdf-opts">
          <el-popconfirm
            confirmButtonText="是"
            cancelButtonText="否"
            title="确定要清空组件吗?"
            @confirm="clearControl"
          >
            <template #reference>
              <el-button
                text
                type="primary"
                :disabled="formData.controls.length == 0"
              >
                <el-icon>
                  <NameIcon name="clear" />
                </el-icon>
                <span>清空</span>
              </el-button>
            </template>
          </el-popconfirm>
          <el-button text type="primary" @click="viewFormJson">
            <el-icon>
              <NameIcon name="json" />
            </el-icon>
            <span>查看JSON</span>
          </el-button>
          <el-button
            text
            type="primary"
            @click="previewForm"
            :disabled="formData.controls.length == 0"
          >
            <el-icon>
              <NameIcon name="preview" />
            </el-icon>
            <span>预览</span>
          </el-button>
          <slot name="button"></slot>
        </div>
      </div> -->
        <div class="form-container" :class="[data.device]">
          <el-form
            ref="form"
            class="form"
            :label-position="formData.props.labelPosition"
            :label-width="formData.props.labelWidth"
            :size="formData.props.size"
            :status-icon="false"
            :show-message="false"
          >
            <ItemRenderer
              :controls="formData.controls"
              @deleteItem="deleteItem"
              @copyItem="copyItem"
            >
              <template #action="{ data }">
                <slot name="action" :data="data"></slot>
              </template>
            </ItemRenderer>
          </el-form>
        </div>
      </div>
    </div>
    <!-- 设计器中间的表单设计区域 end -->
    <!-- 设计器右侧的属性面板 start -->
    <div class="right-board">
      <el-tabs v-model="data.propTab">
        <el-tab-pane label="组件属性" name="control">
          <el-empty
            v-if="data.activeControl == null"
            description="请选择组件"
          ></el-empty>
          <component
            v-else
            :is="types[data.activeControl.type].PropEditor"
            :control="data.activeControl"
            :formProps="formData.props"
            :enData="props.enData"
          />
        </el-tab-pane>
        <el-tab-pane label="表单属性" name="form">
          <FormPropsEditor :formProps="formData.props" />
        </el-tab-pane>
      </el-tabs>
    </div>
    <!-- 设计器右侧的属性面板 end -->
  </div>
</template>

<style lang="scss" scoped>
.container {
  height: 100vh;
  width: 100%;
  border: 1px solid #ccc;
  display: flex;
  .left-board {
    width: 200px;
    height: 100%;
    border-right: 1px solid #ccc;
    overflow: auto;
    .com-title {
      padding: 10px;
      background-color: #f5f7fa;
      border-bottom: 1px solid #ccc;
      el-icon {
        margin-right: 10px;
      }
    }
    .com-group {
      list-style: none;
      padding: 0;
      margin: 0;
      li {
        padding: 10px;
        cursor: pointer;
        border-bottom: 1px solid #ccc;
        &:hover {
          background-color: #f5f7fa;
        }
      }
    }
  }
  .center-board {
    flex: 1;
    height: 100%;
    .toolbar {
    }
    .form-container {
      height: 100%;
      .form {
        border: 1px solid #ccc;
        padding: 10px;
        background-color: orange;
        height: 100%;
        .el-form-item {
          margin-bottom: 10px;
        }
      }
    }
  }
  .right-board {
    width: 300px;
    height: 100%;
    border-left: 1px solid #ccc;
    overflow: auto;
    .el-tabs {
      height: 100%;
      .el-tab-pane {
        padding: 10px;
      }
    }
  }
}
</style>
